// 位运算
// 位运算最关键的几个操作：
// 1.取最右边的 ‘1’：num &= (-num)
// 2.消除最右边的 ‘1‘：num &= (num - 1)
// 3.异或运算 ^：相同为 0（消消乐），不同为 1，无进位相加
// 4.位图的思想：如果题目中提出要求不适用额外的数据结构，那么大概率是要使用位图了
// 5.检查某一个 bit：(num >> x) & 1 == 1
// 6.设置某一个 bit：num |= (1 << x);

// 例题 2：
// 给定一个包含 [0, n] 中 n 个数的数组 nums ，找出 [0, n] 这个范围内没有出现在数组中的那个数。
//
//        示例 1：
//
//        输入：nums = [3,0,1]
//
//        输出：2
//
//        解释：n = 3，因为有 3 个数字，所以所有的数字都在范围 [0,3] 内。2 是丢失的数字，因为它没有出现在 nums 中。
//
//        示例 2：
//
//        输入：nums = [0,1]
//
//        输出：2
//
//        解释：n = 2，因为有 2 个数字，所以所有的数字都在范围 [0,2] 内。2 是丢失的数字，因为它没有出现在 nums 中。
//
//        示例 3：
//
//        输入：nums = [9,6,4,2,3,5,7,0,1]
//
//        输出：8
//
//        解释：n = 9，因为有 9 个数字，所以所有的数字都在范围 [0,9] 内。8 是丢失的数字，因为它没有出现在 nums 中。
//
//        提示：
//
//        n == nums.length
//        1 <= n <= 104
//        0 <= nums[i] <= n
//        nums 中的所有数字都 独一无二
//
//        进阶：你能否实现线性时间复杂度、仅使用额外常数空间的算法解决此问题?

// 解题思路：
// 本题有三种解法：使用 哈希表统计，高斯求和 以及 异或运算
// 哈希表，高斯求和 和 异或运算 的时间复杂度都是 O(n)
// 但是 哈希表 需要消耗额外的空间，因此最好的解法还是 高斯求和 和异或运算

// 心得：
// 这道题是一个无序数组，无序数组找一个缺失的数字的解法就是以上三种解法
// 如果是一个有序数组，这道题最优秀的解法就是二分查找

public class MissingNumber {
    public int missingNumber(int[] nums) {
        int n = nums.length;
        int ret = 0;
        for(int i = 0; i < n; i++){
            ret ^= i;
            ret ^= nums[i];
        }
        return ret ^= n;
    }
}
